"""
@breif 简单的用来测定程序帧率的程序
@author Stone at BlueNet, GDOU
@date Nov. 2020
"""
from collections import deque
import time


class Benchmark:
    """
    usage:
        bm = Benchmark()
        
        while True:
            bm.begin()
            do_something()
            bm.end()
            
            do_something_else()
        
            bm.print_stats()
    """
    def __init__(self, name='', latest_n=5):
        self.name = name
        self.accum_t = 0
        self.accum_recent_dt = 0
        self.latest_n = latest_n
        self.recent_dt = deque(maxlen=latest_n)  # recent dt
        self.recent_dt.append(0)  # to fix bug at initial state
        self.t1 = 0
        self.t2 = 0
        self.n = 0
    
    def begin(self):
        self.t1 = time.time()
    
    def end(self):
        self.t2 = time.time()
        
        # update data
        self.n += 1
        
        dt = self.t2 - self.t1
        self.accum_t += dt
        self.accum_recent_dt -= self.recent_dt[0]
        self.accum_recent_dt += dt
        self.recent_dt.append(dt)
    
    @property
    def fps_average(self):
        try:
            return self.n / self.accum_t
        except ZeroDivisionError:
            return -1
        
    @property
    def fps_recent(self):
        try:
            return len(self.recent_dt) / self.accum_recent_dt
        except ZeroDivisionError:
            return -1
    
    @property
    def avg_t(self):
        try:
            return self.accum_t / self.n
        except ZeroDivisionError:
            return -1
    
    @property
    def avg_t_recent(self):
        try:
            return self.accum_recent_dt / len(self.recent_dt)
        except ZeroDivisionError:
            return -1
    
    def print_stats(self):
        print('<benchmark %s>, %.2f fps, %.3f s; recent avg:%.2f fps, %.3f s' 
            % (self.name, self.fps_average, self.avg_t, self.fps_recent, self.avg_t_recent))
